<?php
//=======================================
//###################################
// Kayako Web Solutions
//
// Source Copyright 2001-2004 Kayako Web Solutions
// Unauthorized reproduction is not allowed
// License Number: %LICENSE%%%
// $Author: vshoor $ ($Date: 2006/04/11 20:58:14 $)
// $RCSfile: functions_cron.php,v $ : $Revision: 1.13 $ 
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//###################################
//=======================================


/*
* Class to manage cron jobs, it doesnt work exactly like the cron scheduler for linux but carries out only basic scheduling functions
*/
class Cron
{
	/*
	* Runs a specific task according $title
	*/
	function runTask()
	{
		global $_SWIFT, $dbCore, $settings, $events, $datastore;

		$title = $_SWIFT["crontitle"];

		$Record = $dbCore->queryFetch("SELECT * FROM `". TABLE_PREFIX ."cron` WHERE `name` = '". $dbCore->escape($title) ."' ORDER BY `nextrun` ASC LIMIT 1;");
		if (empty($Record["cronid"]))
		{
			echo "No Cron Job Found!";
			return false;
		}

		// We now update the next run for this cron job
		$nextruntimeline = $this->saveNextRun($Record);

		// Trigger the cron job for this module
		$_SWIFT["cronid"] = $Record["cronid"];
		$events->triggerCron($Record["module"], $Record["action"]);

		return true;
	}

	/*
	* Runs an already pending task, Should preferably be called through the shutdown function
	*/
	function runPendingTasks()
	{
		global $_SWIFT, $dbCore, $settings, $events, $datastore;
		
		$nextrunlist = array();

		$queryresult = $dbCore->query("SELECT * FROM `". TABLE_PREFIX ."cron` WHERE `nextrun` <= '". DATENOW ."' AND `autorun` = '1' ORDER BY `nextrun` ASC;");
		if (!$queryresult)
		{
			return false;
		}

		while ($dbCore->nextRecord())
		{
			$Record = $dbCore->Record;

			if (empty($Record["cronid"]))
			{
				//return false;
			}

			// We now update the next run for this cron job
			$nextrunlist[] = $this->saveNextRun($Record);

			$_SWIFT["cronid"] = $Record["cronid"];
			// Trigger the cron job for this module
			$events->triggerCron($Record["module"], $Record["action"]);
		}

		array_multisort($nextrunlist, SORT_ASC, SORT_NUMERIC);
		
		if (trim($nextrunlist[0]) != "")
		{
			$queryresult = $dbCore->query("SELECT `nextrun` FROM `". TABLE_PREFIX ."cron` WHERE `nextrun` <= '". DATENOW ."' AND `autorun` = '1' ORDER BY `nextrun` ASC;");
			if (!$queryresult)
			{
				return false;
			}

			$dbCore->nextRecord();
			if (trim($dbCore->Record["nextrun"]) != "")
			{
				$settings->updateKey("cron", "nextrun", $dbCore->Record["nextrun"], true);
			}
		} else {
			// This shouldnt be happening but if it does set nextrun to 1 hour from now
			$settings->updateKey("cron", "nextrun", DATENOW+3600, true);
		}

		return true;
	}

	/*
	* This function calculates the next run time for a particular cron task
	*/
	function saveNextRun($Record)
	{
		global $_SWIFT, $dbCore;

		// This is a very basic cron function, we wont need scripts to run at specific time of day so I didnt add specific time processing to this
		
		$nextrun = $Record["nextrun"];
		$savenextrun = 0;


		if ($Record["cminute"] == -1 && $Record["cday"] == 0 && $Record["chour"] == 0)
		{
			// Append one minute to this and save
			$savenextrun = $this->addMinute($nextrun);
		} else if ($Record["cminute"] > 0 && $Record["cday"] == 0 && $Record["chour"] == 0) {
			// Append $cminute to this and save, this means we run it every x minutes
			$savenextrun = $this->addMinute($nextrun, $Record["cminute"]);
		} else if ($Record["chour"] == -1 && $Record["cday"] == 0 && $Record["cminute"] == 0) {
			// We run this every 1 hour
			$savenextrun = $this->addHour($nextrun);
		} else if ($Record["chour"] > 0 && $Record["cday"] == 0 && $Record["cminute"] == 0) {
			// We run this every x hour
			$savenextrun = $this->addHour($nextrun, $Record["chour"]);
		} else if ($Record["cday"] == -1 && $Record["cminute"] == 0 && $Record["chour"] == 0) {
			// We run this every day
			$savenextrun = $this->addDay($nextrun);
		} else if ($Record["cday"] > 0 && $Record["chour"] == 0 && $Record["cminute"] == 0) {
			// We run this every x days
			$savenextrun = $this->addDay($nextrun, $Record["cday"]);
		}

		if ($savenextrun < DATENOW)
		{
			// Seems like there was some clocking resetting here, time to set the date to a future one
			$savenextrun = DATENOW+1;
		}

		// We have save next run now, save it over
		if ($savenextrun)
		{
			$dbCore->query("UPDATE `". TABLE_PREFIX ."cron` SET `nextrun` = '". $savenextrun ."', `lastrun` = '". DATENOW ."' WHERE `cronid` = '". intval($Record["cronid"]) ."';", 2);
		}

		return $savenextrun;
	}

	/*
	* Adds day to a dateline, if cday is specified we append x days to dateline
	*/
	function addDay($dateline, $cday=0)
	{
		if (!$cday)
		{
			return $dateline+(1*60*60*24);
		} else {
			return $dateline+($cday*60*60*24);
		}
	}

	/*
	* Adds hour to specified dateline, if chour is specified we just append x hours to dateline
	*/
	function addHour($dateline, $chour=0)
	{
		if (!$chour)
		{
			return $dateline+(1*60*60);
		} else {
			return $dateline+($chour*60*60);
		}		
	}

	/*
	* Adds minute to dateline, if cminute is specified we append x minutes to dateline
	*/
	function addMinute($dateline, $cminute=0)
	{
		if (!$cminute)
		{
			return $dateline+(60);
		} else {
			return $dateline+($cminute*60);
		}	
	}

	/**
	* Adds a Log Entry into cronlog table
	*/
	function logentry($cronid, $descname)
	{
		global $_SWIFT, $dbCore, $template;

		if (!$cronid)
		{
			return;
		}

		$template->loadLanguageSection("tasks");

		$dbCore->query("SELECT * FROM `". TABLE_PREFIX ."cron` WHERE `cronid` = '". $dbCore->escape($cronid) ."';");
		$dbCore->nextRecord();

		if ($dbCore->Record["cronid"] == "")
		{
			return false;
		}

		$crontitle = $_SWIFT["language"][$dbCore->Record["name"]];

		$dbCore->query("INSERT INTO `". TABLE_PREFIX ."cronlogs` (`cronid`, `crontitle`, `dateline`, `description`) VALUES ('". intval($cronid) ."', '". $dbCore->escape($crontitle) ."', '". DATENOW ."', '". $dbCore->escape($_SWIFT["language"][$descname]) ."');");
	}

	/**
	* Deletes the task logs
	*/
	function deleteTaskLogs($cronlogidarray)
	{
		global $dbCore, $_SWIFT;

		if (!is_array($cronlogidarray))
		{
			return false;
		}

		$dbCore->query("DELETE FROM `". TABLE_PREFIX ."cronlogs` WHERE `cronlogid` IN (". buildIN($cronlogidarray) .");");

		return true;
	}
}
?>